home *** CD-ROM | disk | FTP | other *** search
/ L' Effet Pommier 3 / L'Effet Pommier - Volume 03.iso / Programmation / Alpha ƒ / Tcl / SystemCode / eudora.tcl < prev    next >
Text File  |  1996-01-15  |  23KB  |  849 lines

  1. #     <nowrap>
  2. # Built for Eudora
  3.  
  4. # Class message: A message
  5. # Elements:
  6. #     field by name
  7. # Properties:
  8. #     body  string  -- the body of the message
  9. #     priority  integer  -- the priority
  10. #     label  integer  -- the index of the label
  11. #     status  unread/already read/replied/forwarded/redirected/not sendable/sendable/queued/sent/never sent  -- the message status
  12. #     sender  string  -- the sender as appearing in the message summary
  13. #     date  string  [r/o]  -- the date as appearing in the message summary
  14. #     subject  string  -- the subject as appearing in the message summary
  15. #     size  integer  [r/o]  -- the size of the message
  16. #     outgoing  boolean  [r/o]  -- is the message is outgoing?
  17. #     signature  none/standard/alternate  -- which signature the message should have
  18. #     QP  boolean  -- is Eudora allowed to encode text?
  19. #     return receipt  boolean  -- is a return receipt is requested?
  20. #     wrap  boolean  -- should the text be wrapped when sent?
  21. #     tab expansion  boolean  -- should tabs get expanded to spaces?
  22. #     keep copy  boolean  -- should a copy should be kept after message is sent?
  23. #     preserve macintosh info  boolean  -- should Macintosh information always be sent with attachments?
  24. #     attachment encoding  AppleDouble/AppleSingle/BinHex/uuencode  -- the type of encoding to use for attachments
  25. #     show all headers  boolean  -- should all headers be visible?
  26. #     transliteration table  integer  -- the resource id of the transliteration table
  27. #     will be fetched  boolean  -- will the message be [re]fetched on next check?
  28. #     will be deleted  boolean  -- will the message be deleted from server on next check?
  29.  
  30. proc mailMenu {} {}
  31. proc dummyMail {} {}
  32.  
  33.  
  34. proc showEudoraMenuProc {flag} {
  35.     global showEudoraMenu mailMenu
  36.     
  37.     if {$showEudoraMenu} {
  38.         insertMenu $mailMenu
  39.     } else {
  40.         removeMenu $mailMenu
  41.     }
  42. }
  43.  
  44. #===============================================================================
  45. newModeVar Mail tossOnQueue        1    1
  46. newModeVar Mail    switchOnQueue    0    1
  47. newModeVar Mail    immediateSend    0    1
  48. #===============================================================================
  49. # Utility routines.
  50. proc eudoraFolder {} { nameObject euMF {'TEXT'()} [nullObject] }
  51. proc mailboxByName {name} { nameObject euMB "╥$name╙" [eudoraFolder] }
  52. proc mailboxByIndex {ind} { indexObject euMB $ind [eudoraFolder] }
  53. proc eudoraMessage {msg_id mailbox} { indexObject euMS $msg_id [mailboxByName $mailbox] }
  54. proc mailboxProperty {prop mailbox} { objectProperty 'CSOm' $prop [mailboxByName $mailbox] }
  55. proc messageProperty {prop msg_id mailbox} { objectProperty 'CSOm' $prop [eudoraMessage $msg_id $mailbox] }
  56.  
  57. # Get path-name for indicated mailbox
  58. proc mailboxPathName {name} {
  59.     extractPath [mailboxProperty euFS $name]
  60. }
  61.  
  62. proc mailboxPathIndex {ind} {
  63.     set res [objectProperty 'CSOm' euFS [mailboxByIndex $ind]]
  64.     return [extractPath $res]
  65. }
  66.  
  67. #===============================================================================
  68.  
  69.  
  70. proc checkMailPath {} {
  71.     global mailPath modifiedVars
  72.     return [checkRunning "Mail app:" "CSOm" mailPath]
  73. }
  74.  
  75. if {![info exists eudoraBoxes]} {
  76.     set eudoraBoxes {In Out}
  77. }
  78.  
  79. menu -n $mailMenu -p eudoraProc {
  80.     "<SbackgroundEudora"
  81.     "<Seudora"
  82.     "help"
  83.     "(-"
  84.     "/e<UnewMessage"
  85.     "cc"
  86.     "bcc"
  87.     "(-"
  88.     "/f<Usend"
  89.     "/g<Ureply"
  90.     "(-"
  91.     "updateMailboxLists"
  92.     "/h<UopenMailbox╔"
  93.     {menu -n open -p mailBoxProc -m {}}
  94.     "(-"
  95.     "/i<UmoveToTrash"
  96.     "/j<UmoveToMailbox╔"
  97.     {menu -n moveTo -p transferProc -m {}}
  98.     "(-"
  99.     {menu -n tellEudora -p eudoraProc {
  100.         "/k<UflushOutbox"
  101.         "/l<UcheckForMail"
  102.         "(-"
  103.         startNotifying
  104.         stopNotifying}}
  105.     {menu -n mailFlags -p mailFlagsProc {flushOnCheck alertOnIncoming}}
  106. }
  107. menu -n open -p mailBoxProc -m $eudoraBoxes
  108. menu -n moveTo -p transferProc -m $eudoraBoxes
  109.  
  110.  
  111. proc openMailbox {} {
  112.     global eudoraBoxes eudoraLastFolder modifiedVars
  113.     if {[info exists eudoraLastFolder]} {
  114.         set fold $eudoraLastFolder
  115.     } else {
  116.         set fold [lindex $eudoraBoxes 0]
  117.     }
  118.     set eudoraLastFolder [sPromptChoices "Open mailbox" $fold $eudoraBoxes]
  119.     mailBoxProc dummy $eudoraLastFolder
  120.     lappend modifiedVars eudoraLastFolder
  121. }
  122.  
  123.  
  124. proc moveToFolderProc {curr c} {
  125.     global eudoraBoxes
  126.     if {$c != "\t"} {return $c}
  127.     
  128.     set matches {}
  129.     foreach w $eudoraBoxes {
  130.         if {[string match "$curr*" $w]} {
  131.             lappend matches $w
  132.         }
  133.     }
  134.     if {![llength $matches]} {
  135.         beep
  136.     } else {
  137.         return [string range [largestPrefix $matches] [string length $curr] end]
  138.     }
  139.     return ""
  140. }
  141.  
  142.  
  143. proc moveToMailbox {} {
  144.     global eudoraLastFolder modifiedVars
  145.     
  146.     if {[info exists eudoraLastFolder]} {
  147.         set fold $eudoraLastFolder
  148.     } else {
  149.         set fold Trash
  150.     }
  151.     
  152.     set folder [statusPrompt -f "Move to ($fold): " moveToFolderProc]
  153.     if {[string length $folder]} {
  154.         doFolderMove $folder
  155.         set eudoraLastFolder $folder
  156.         lappend modifiedVars eudoraLastFolder
  157.     } else {
  158.         doFolderMove $fold
  159.     }
  160. }
  161.  
  162.  
  163. proc eudoraProc {menu item} {
  164.     global mailPath HOME
  165.     global mailMenu
  166.  
  167.     if {![info exists mailPath] || ![file exists $mailPath]} {
  168.         alertnote "Please set 'Eudora Path' via menu item\r \"Config:App Paths\"."
  169.         return
  170.     }
  171.     
  172.     if {![string match {*udora} $item]} {
  173.         checkRunning "Eudora" {CSOm} mailPath
  174.     }
  175.  
  176.     switch $item {
  177.         "eudora"        {launch -f $mailPath}
  178.         "backgroundEudora"        {launch $mailPath}
  179.         "help"            {edit -r "$HOME:Help:Eudora"}
  180.         "cc"            {eudoraCc}
  181.         "bcc"            {eudoraBcc}
  182.         "newMessage"    {mailNewMsg}
  183.         "reply"            {mailReplymsg}
  184.         "send"            {checkMailPath; mailSendCreatedMsg}
  185.         "flushOutbox"    {checkMailPath; mailFlushOut}
  186.         "checkForMail"    {checkMailPath; mailCheck}
  187.         "startNotifying" "checkMailPath; startNotifying"
  188.         "stopNotifying"    "checkMailPath; stopNotifying"
  189.         "moveToTrash"    {mailTrashmsg}
  190.         "Create New"    {eudoraNewMailbox}
  191.         "Delete"        {eudoraDeleteMailbox}
  192.         default            $item
  193.     }
  194. }
  195.  
  196. if {![info exists mailflushOnCheck]} {set mailflushOnCheck 1}
  197. if {![info exists mailalertOnIncoming]} {set mailalertOnIncoming 1}
  198. markMenuItem mailFlags flushOnCheck $mailflushOnCheck
  199. markMenuItem mailFlags alertOnIncoming $mailalertOnIncoming
  200.  
  201.  
  202. proc mailFlagsProc {menu flag} {
  203.     global mail$flag modifiedVars
  204.     set mail$flag [expr 1 - [set mail$flag]]
  205.     lappend modifiedVars mail$flag
  206.     markMenuItem mailFlags $flag [set mail$flag]
  207. }
  208.  
  209.  
  210. # Works, but eudora doesn't immediately flush mailboxes
  211. # proc directMailbox {menu folder} {
  212. #     global inboxMembers ALPHA eudoraBoxes modifiedVars
  213. #     global tileLeft tileTop tileWidth tileHeight errorHeight
  214. #     killMailboxWindow
  215. #     checkMailPath
  216. #     switchTo $ALPHA
  217. #     global trashedMsgs$folder
  218. #     set trashedMsgs$folder {}
  219. #     
  220. #     set res [AEBuild -r 'CSOm' core getd ---- "obj \{form:prop, want:type(prop), seld:type(euFS), from:obj \{form:indx, want:type(euMB), seld:[expr [lsearch $eudoraBoxes $folder] + 1], from:obj \{form:name, want:type(euMF), seld:'TEXT'(), from:'null'()\}\}\}" ]
  221. #     if {![regexp {╟(.*)╚} $res dummy fss]} return
  222. #     set name [file tail [set fname [specToPathName $fss]]]
  223. #     if {$name != $folder} {
  224. #         beep
  225. #         message "You need to update your mailbox lists."
  226. #         return
  227. #     }
  228. #     message $name
  229. #     set fd [open $fname]
  230. #     set text {}
  231. #     set ind 1
  232. #     set inboxMembers {}
  233. #     foreach ln [split [read $fd] "\r\n"] {
  234. #         if {[regexp {^From:} $ln dummy]} {
  235. #             regexp {[a-zA-Z0-9_.]+@[a-zA-Z0-9_.]+} $ln from
  236. #         } elseif {![regexp {^Subject: (.*)} $ln dummy subject]} continue
  237. #         if {[info exists from] && [info exists subject]} {
  238. #             set tag {}
  239. #             while {[lsearch $inboxMembers $from$tag] >= 0} {
  240. #                 if {![string length $tag]} {
  241. #                     set tag { <2>}
  242. #                 } else {
  243. #                     regexp {[0-9]+} $tag tag
  244. #                     set tag " <[expr $tag + 1]>"
  245. #                 }
  246. #             }
  247. #             append text [format "%-40s : %s\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t░$folder░$ind\r" $from$tag $subject]
  248. #             lappend inboxMembers $from$tag
  249. #             incr ind
  250. #             
  251. #             unset from; unset subject
  252. #         }
  253. #     }
  254. #     close $fd
  255. #     if {![string length $text]} {
  256. #         alertnote "No messages in '$folder'!"
  257. #         return
  258. #     }
  259. #     
  260. #     new -n "* MAILBOX '$folder' *" -g $tileLeft $tileTop $tileWidth $errorHeight
  261. #     global winModes
  262. #     set name [lindex [winNames] 0]
  263. #     changeMode [set winModes($name) Brws]
  264. #     insertText "(<cr> to go to message)\r-----\r$text"
  265. #     
  266. #     select [nextLineStart [nextLineStart 0]] [nextLineStart [nextLineStart [nextLineStart 0]]]
  267. #     setWinInfo dirty 0
  268. #     setWinInfo read-only 1
  269. #     message ""
  270. # }
  271.  
  272. proc mailBoxProc {menu item} {
  273.     global inboxMembers ALPHA eudoraBoxes modifiedVars
  274.     global tileLeft tileTop tileWidth tileHeight errorHeight
  275.  
  276.     killMailboxWindow
  277.  
  278.     checkMailPath
  279.     switchTo $ALPHA
  280.  
  281.     global trashedMsgs$item
  282.     set trashedMsgs$item {}
  283.     
  284.     set inboxMembers {}
  285.     set text {}
  286.     set ind 1
  287.     foreach msg [mailSenders $item] {
  288.         set from [mailAddr [lindex $msg 0]]
  289.         set tag {}
  290.         while {[lsearch $inboxMembers $from$tag] >= 0} {
  291.             if {![string length $tag]} {
  292.                 set tag { <2>}
  293.             } else {
  294.                 regexp {[0-9]+} $tag tag
  295.                 set tag " <[expr $tag + 1]>"
  296.             }
  297.         }
  298.         append text [format "%-40s : %s\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t░$item░$ind\r" "$from$tag" [lindex $msg 1]]
  299.         lappend inboxMembers $from$tag
  300.         incr ind
  301.     }
  302.     if {![string length $text]} {
  303.         alertnote "No messages in '$item'!"
  304.         return
  305.     }
  306.     
  307.     new -n "* MAILBOX '$item' *" -g $tileLeft $tileTop $tileWidth $errorHeight
  308.     global winModes
  309.     set name [lindex [winNames] 0]
  310.     changeMode [set winModes($name) Brws]
  311.  
  312.     insertText "(<cr> to go to message)\r-----\r$text"
  313.     
  314.     select [nextLineStart [nextLineStart 0]] [nextLineStart [nextLineStart [nextLineStart 0]]]
  315.     setWinInfo dirty 0
  316.     setWinInfo read-only 1
  317.     message ""
  318. }
  319.  
  320. proc eudoraNewMailbox {} {
  321. }
  322.  
  323.  
  324. proc eudoraDeleteMailbox {} {
  325. }
  326.  
  327.  
  328. proc killMailboxWindow {} {
  329.     if {[set ind [lsearch [winNames] {*MAILBOX*}]] >= 0} {
  330.         set win [lindex [winNames] $ind]
  331.         bringToFront $win
  332.         killWindow
  333.     }
  334. }
  335.  
  336.  
  337. proc mailGotoMatch {} {
  338.     if {[regexp {░(.+)░([0-9]+)} [getText [lineStart [getPos]] [nextLineStart [getPos]]] dummy folder ind]} {
  339.         global trashedMsgs$folder
  340.         
  341.         set deleted 0
  342.         for {set i 1} {$i < $ind} {incr i} {
  343.             if {[lsearch [set trashedMsgs$folder] $i] >= 0} {
  344.                 incr deleted
  345.             }
  346.         }
  347.         mailOpen $folder [expr $ind - $deleted] $ind
  348.     }
  349. }
  350.  
  351.  
  352. proc mailAddr {name} {
  353.     if {![regexp {<(.*)>} $name dummy addr]} {
  354.         regexp {^[^ ]+} $name addr
  355.     }
  356.     return $addr
  357. }
  358.  
  359.  
  360. proc mailSenders {folder} {
  361.     set cnt [mailCountMsgs $folder]
  362.     set msgs {}
  363.     for {set i 1} {$i <= $cnt} {incr i} {
  364.         set subject {}
  365.         regexp {From: (.*)} [mailGetField from $folder $i] dummy from
  366.         regexp {Subject: (.*)} [mailGetField subject $folder $i] dummy subject
  367.         lappend msgs [list $from $subject]
  368.     }
  369.     return $msgs
  370. }    
  371.  
  372.  
  373. proc eudoraCc {} {
  374.     if {![catch {set res [search -s -f 1 -r 1 -i 1 {cc:.*} 0]}]} {
  375.         goto [lindex $res 0]
  376.         endOfLine
  377.     } else {
  378.         beginningOfBuffer
  379.         nextLine
  380.         insertText "Cc: \r"
  381.         backwardChar
  382.     }
  383. }
  384.  
  385.  
  386. proc eudoraBcc {} {
  387.     if {![catch {set res [search -s -f 1 -r 1 -i 1 {bcc:.*} 0]}]} {
  388.         goto [lindex $res 0]
  389.         endOfLine
  390.     } else {
  391.         beginningOfBuffer
  392.         nextLine
  393.         insertText "Bcc: \r"
  394.         backwardChar
  395.     }
  396. }
  397.  
  398.  
  399. proc mailFlushOut {} {
  400.     global MailmodeVars
  401.     message "Telling Eudora to flush messages╔"
  402.  
  403.     AEBuild 'CSOm' CSOm eCon eSen bool(╟01╚) eChk bool(╟00╚)
  404.     message ""
  405. }
  406.  
  407.  
  408. proc mailCheck {} {
  409.     global MailmodeVars mailflushOnCheck
  410.     message "Told Eudora to check for new mail╔"
  411.  
  412.     AEBuild 'CSOm' CSOm eCon eSen bool(╟0$mailflushOnCheck╚) eChk bool(╟01╚)
  413. }
  414.  
  415.  
  416. proc mailReplymsg {} {
  417.     global inboxMembers
  418.  
  419.     set prefix "> "
  420.     set res [search -s -f 1 -r 1 {^>==} 0]
  421.     set header [getText 0 [lindex $res 0]]
  422.     
  423.     set from [mailGetFrom]
  424.     if {![regexp {Subject: ([^\r]*)} $header dummy subject]} {set subject ""}
  425.     set body [getText [expr [lindex $res 1] + 1] [maxPos]]
  426.  
  427.     regsub -all "\r" $body "\r$prefix" body
  428.     mailNewMsg $from "Re: $subject" "\r$prefix$body\r"
  429. }
  430.  
  431. proc transferProc {menu item} {
  432.     doFolderMove $item
  433. }
  434.  
  435.  
  436. proc mailTrashmsg {} {
  437.     doFolderMove Trash
  438. }
  439.  
  440. proc doFolderMove {toFolder} {
  441.     # Is this a summary or msg window?
  442.     if {[regexp "MAILBOX" [lindex [winNames] 0]]} {
  443.         if {![regexp {░(.*)░([0-9]+)} [getText [getPos] [nextLineStart [getPos]]] dummy folder orig]} {
  444.             beep
  445.             return
  446.         }
  447.         if {$toFolder == $folder} return
  448.         global trashedMsgs$folder
  449.  
  450.         set deleted 0
  451.         for {set i 1} {$i < $orig} {incr i} {
  452.             if {[lsearch [set trashedMsgs$folder] $i] >= 0} {
  453.                 incr deleted
  454.             }
  455.         }
  456.         set number [expr $orig - $deleted]
  457.         set summary 1
  458.     } else {
  459.         set pos [lindex [search -f 1 -r 1 {^Msg} 0] 0]
  460.         set text [getText $pos [nextLineStart $pos]]
  461.         regexp {"([^"]+)" \(([0-9]+)\).*"([^"]+)"} $text dummy number orig folder
  462.         if {$toFolder == $folder} return
  463.         set summary 0
  464.  
  465.         global trashedMsgs$folder
  466.     }
  467.     
  468.     message "Moving msg $number ($orig) of folder '$folder' to '$toFolder'"
  469.     moveMsg $number $folder $toFolder
  470.     if {!$summary} killWindow
  471.  
  472.     lappend trashedMsgs$folder $orig
  473.     
  474.     # Find summary info and delete it
  475.     set win [lindex [winNames] 0]
  476.     if {[regexp "MAILBOX" $win]} {
  477.         setWinInfo read-only 0
  478.     
  479.         set inds [search -f 1 -r 1 "░$folder░$orig\$" 0]
  480.         set pos [lindex $inds 0]
  481.         deleteText [lineStart $pos] [nextLineStart $pos]
  482.     
  483.         if {[string length [search -n -f 1 -r 0 {░} 0]]} {
  484.             setWinInfo dirty 0
  485.             setWinInfo read-only 1
  486.     
  487.             nextLine
  488.             upBrowse
  489.         } else {
  490.             setWinInfo dirty 0
  491.             killWindow
  492.         }
  493.     }
  494. }
  495.  
  496.     
  497. proc mailGetFrom {} {
  498.     set res [search -s -f 1 -r 1 {>==} 0]
  499.     set header [getText 0 [lindex $res 0]]
  500.     if {[regexp {From: ([^\r]*)} $header dummy from]} {
  501.         return [mailAddr $from]
  502.     }
  503.     error "No from line"
  504. }
  505.  
  506.     
  507.  
  508. proc mailSendCreatedMsg {} {
  509.     global MailmodeVars
  510.     
  511.     set name [checkMailPath]
  512.     set res [search -s -f 1 -r 0 {>==text follows this line==<} 0]
  513.     set header [getText 0 [lindex $res 0]]
  514.     
  515.     if {![regexp {To: ([^\r]*)} $header dummy to]} {set to ""}
  516.     if {![regexp {Cc: ([^\r]*)} $header dummy cc]} {set cc ""}
  517.     if {![regexp {Subject: ([^\r]*)} $header dummy subject]} {set subject ""}
  518.  
  519.     set body [getText [expr [lindex $res 1] + 1] [maxPos]]
  520.     
  521.     mailCreateMsg
  522.     mailSetField to $to
  523.     mailSetField cc $cc
  524.     mailSetField subject $subject
  525.     mailSetField "" $body
  526.     
  527.     if {$MailmodeVars(tossOnQueue)} {
  528.         setWinInfo dirty 0
  529.         killWindow
  530.     }
  531.  
  532.     mailQueueLast
  533.  
  534.     if {$MailmodeVars(switchOnQueue)} {
  535.         switchTo $name
  536.     }
  537.  
  538.     if {$MailmodeVars(immediateSend)} {
  539.         mailFlushOut
  540.     } else {
  541.         message "Message queued╔"
  542.     }
  543. }
  544.  
  545.     
  546. proc mailNewMsg {{to ""} {subject ""} {body ""}} {
  547.     new -n "New Mail"
  548.     global winModes
  549.     set name [lindex [winNames] 0]
  550.     changeMode [set winModes($name) Mail]
  551.  
  552.     insertText "To: $to\rSubject: $subject\r>==text follows this line==<\r$body"
  553.     setWinInfo dirty 0
  554.     goto 0
  555.     centerRedraw
  556.     mailTab
  557. }
  558.  
  559.  
  560. proc mailTab {} {
  561.     global mailKeywords
  562.     if {[catch {search -s -f 1 -r 1 -i 1 "([join $mailKeywords {|}]|^>)" [getPos]} res]} {
  563.         insertText "\t"
  564.         return
  565.     }
  566.     if {[lookAt [lindex $res 0]] == ">"} {
  567.         select [nextLineStart [lindex $res 1]] [maxPos]
  568.     } else {
  569.         goto [expr [lindex $res 1] + 1]
  570.         endLineSelect
  571.     }
  572. }
  573. bind '\t'                         mailTab Mail
  574.  
  575.  
  576. proc mailOpen {folder i originalNum} {
  577.     global tileLeft tileTop tileHeight trashedMsgs$folder
  578.     
  579.     set from [mailGetField From $folder $i]
  580.     set to [mailGetField To $folder $i]
  581.     set subject [mailGetField Subject $folder $i]
  582.     set sender [mailGetField Sender $folder $i]
  583.     set cc [mailGetField cc $folder $i]
  584.     set contents [mailGetField "" $folder $i]
  585.     
  586. #===============================================================================
  587.     global tileHeight tileWidth tileTop tileLeft errorHeight errorDisp
  588.     set top $tileTop
  589.     set geo [getGeometry]
  590.     if {([lindex $geo 0] != $tileLeft) || ([lindex $geo 1] != $top) || ([lindex $geo 2] != $tileWidth) || ([lindex $geo 3] != $errorHeight) } {
  591.         moveWin $tileLeft $top
  592.         sizeWin $tileWidth $errorHeight
  593.     }
  594.     set mar 28
  595.     incr top [expr $errorHeight + $mar]
  596. #===============================================================================
  597.     new -n "MAIL" -g $tileLeft $top $tileWidth [expr $errorDisp - 5]
  598.  
  599.     global winModes
  600.     set name [lindex [winNames] 0]
  601.     changeMode [set winModes($name) Mail]
  602.  
  603.     set text {}
  604.     if {[string length $subject]} {append text "$subject\r"}
  605.     if {[string length $to]} {append text "$to\r"}
  606.     if {[string length $from]} {append text "$from\r"}
  607.     if {[string length $cc]} {append text "$cc\r"}
  608.     if {[string length $sender]} {append text "$sender\r"}
  609.     append text "Msg \"$i\" ($originalNum) of mailbox \"$folder\"     Reply     Trash\r"
  610.     insertText "${text}>===============================================================================
  611. $contents
  612. "
  613.     goto 0
  614.     goto [lindex [search -f 1 -r 1 {^Msg "} 0] 0]
  615.     set pos [getPos]
  616.     regexp -indices {([0-9]+).*mailbox "(.+)".*(Reply).*(Trash)} [getText $pos [nextLineStart $pos]] dummy num fold rep tra
  617.     colorSelectPos [expr $pos + [lindex $num 0]] [expr 1 + $pos + [lindex $num 1]] bold 12
  618.     colorSelectPos [expr $pos + [lindex $fold 0]] [expr 1 +$pos + [lindex $fold 1]] bold 12
  619.     hyperSelectPos [expr $pos + [lindex $rep 0]] [expr 1 +$pos + [lindex $rep 1]] "mailReplymsg"
  620.     hyperSelectPos [expr $pos + [lindex $tra 0]] [expr 1 +$pos + [lindex $tra 1]] "mailTrashmsg"
  621.  
  622.     goto 0
  623.     setWinInfo dirty 0
  624.     setWinInfo read-only 1
  625.     centerRedraw
  626. }
  627.  
  628. proc colorSelectPos {from to ind ind2} {
  629.     insertColorEscape $from $ind
  630.     insertColorEscape $to $ind2
  631. }
  632.  
  633. proc hyperSelectPos {from to text} {
  634.     if {$from == $to} {
  635.         beep
  636.         return
  637.     }
  638.     insertColorEscape $from 3
  639.     insertColorEscape $from 15 $text
  640.     insertColorEscape $to 12
  641.     insertColorEscape $to 0
  642. }
  643.  
  644. proc mailFixMenus {} {
  645.     global mailMenu
  646.     
  647.     set ins {}
  648.     set outs {}
  649.     
  650.     set cnt [mailCountMsgs in]
  651.     for {set i 1} {$i <= $cnt} {incr i} {
  652.         lappend ins [mailGetField from in $i]
  653.     }
  654.     menu -n in {}
  655.     foreach item $ins {
  656.         addMenuItem -l "" in $item
  657.     }
  658.     
  659.     set cnt [mailCountMsgs out]
  660.     for {set i 1} {$i <= $cnt} {incr i} {
  661.         lappend outs [mailGetField from out $i]
  662.     }
  663.     menu -n out {}
  664.     foreach item $outs {
  665.         addMenuItem -l "" out $item
  666.     }
  667. }
  668.  
  669.  
  670. # make message at end of mailbox "out" of mail folder ""
  671. proc mailCreateMsg {} {
  672.     createThingAtEnd 'CSOm' [mailboxByName Out] euMS
  673. }
  674.  
  675.  
  676. # Move msg w/ specified index between folders, including to Trash.
  677. proc moveMsg {msg infolder outfolder} {
  678.     AEBuild -r 'CSOm' core move {----} "obj \{form:indx, want:type(euMS), seld:$msg, from:obj \{form:name, want:type(euMB), seld:╥$infolder╙, from:obj \{form:name, want:type(euMF), seld:'TEXT'(), from:'null'()\}\}\}" {insh} "insl\{kobj:obj \{form:name, want:type(euMB), seld:╥$outfolder╙, from:obj \{form:name, want:type(euMF), seld:'TEXT'(), from:'null'()\}\}, kpos:end \}"
  679. }
  680.  
  681.  
  682. # set field "fld" of message 0 to "to"
  683. proc mailSetField {fld to} {
  684.     AEBuild -r 'CSOm' core setd {----} "obj \{form:name, want:type(euFd), seld:╥$fld╙, from:obj \{form:indx, want:type(euMS), seld:1, from:'null'()\}\}" data "╥$to╙"
  685. }
  686.  
  687. proc mailGetField {field folder msg} {
  688.     if {[catch {getObjectData 'CSOm' euFd $field [eudoraMessage $msg $folder]} res]} {
  689.         return ""
  690.     } else {
  691.         return $res
  692.     }
  693. }
  694.  
  695. # obj {want:type('prop'), from:obj {form:indx, want:type(euMS), seld:$msg, from:obj {form:name, want:type(euMB), seld:╥$folder╙, from:obj {form:name, want:type(euMF), seld:'TEXT'(), from:'null'()}}}, form:'prop', seld:type('euST')}
  696.  
  697. proc mailMsgStatus {folder msg} {
  698.     if {[catch {AEBuild -r 'CSOm' core getd {----} "obj \{want:type('prop'), from:obj \{form:indx, want:type(euMS), seld:$msg, from:obj \{form:name, want:type(euMB), seld:╥$folder╙, from:obj \{form:name, want:type(euMF), seld:'TEXT'(), from:'null'()\}\}\}, form:'prop', seld:type('euST')\}"} text]} {
  699.         return ""
  700.     }
  701.     set from [string first "╥" $text]
  702.     set to [string first "╙" $text]
  703.     return [string range $text [expr $from + 1] [expr $to - 1]]
  704. }
  705.  
  706. proc mailQueueLast {} {
  707.     AEBuild -r 'CSOm' CSOm eQue ---- {obj {form:indx, want:type(euMS), seld:1, from:'null'()}}
  708. }
  709.  
  710. # CSOm\eAtc{'----':obj {form:indx, want:type(euMS), seld:1, from:'null'()}, eDcl:[fss (╟486172643A4465736B746F7020466F6C6465723A62756773╚)]}
  711. proc mailAttachmentDoesntWork {name} {
  712.     AEBuild -r 'CSOm' CSOm eAtc ---- {obj {form:indx, want:type(euMS), seld:1, from:'null'()}} eDcl [makeAlis $name]
  713. }
  714.  
  715. # core\setd{'----':obj {form:prop, want:type(prop), seld:type(euPY), from:obj {form:indx, want:type(euMS), seld:1, from:'null'()}}, data:1}
  716. proc mailSetNumberProperty {prop to} {
  717.     AEBuild -r 'CSOm' core setd ---- "obj \{form:prop, want:type(prop), seld:type($prop), from:obj \{form:indx, want:type(euMS), seld:1, from:'null'()\}\}" data $to
  718. }    
  719.  
  720.  
  721. proc mailCountMsgs {mbox} {
  722.     return [countObjects 'CSOm' [mailboxByName "$mbox"]  euMS]
  723. }
  724.  
  725. proc mailCountMailboxes {} {
  726.      return [countObjects 'CSOm' [eudoraFolder] euMB]
  727. }
  728.     
  729.  
  730. proc updateMailboxLists {} {
  731.     set num [mailCountMailboxes]
  732.     for {set i 1} {$i <= $num} {incr i} {
  733.         set name [file tail [mailboxPathIndex $i]]
  734.         message $name
  735.         lappend boxes $name
  736.     }
  737.     
  738.     global eudoraBoxes modifiedVars
  739.     lappend modifiedVars eudoraBoxes
  740.     set eudoraBoxes $boxes
  741.     menu -n open -p mailBoxProc -m $eudoraBoxes
  742.     menu -n moveTo -p transferProc -m $eudoraBoxes
  743.     message "done."
  744. }
  745.  
  746.  
  747. #===============================================================================
  748.  
  749. eventHandler CSOm eNot "eudoraHandler"
  750.  
  751. # a sample 'msgs': obj {want:type(euMS), from:obj {want:type(euMB), from:obj {want:type(euMF), from:'null'(), form:name, seld:'TEXT'()}, form:name, seld:╥In╙}, form:indx, seld:18}, obj {want:type(euMS), from:obj {want:type(euMB), from:obj {want:type(euMF), from:'null'(), form:name, seld:'TEXT'()}, form:name, seld:╥In╙}, form:indx, seld:19}
  752. proc eudoraHandler {it} {
  753.     global blah mailalertOnIncoming
  754.     message ""
  755.     if {[regexp {eWHp:wArv.*\[(obj.*)\], &repq} $it dum1 msgs]} {
  756.         set ids [getMsgIDs $msgs]
  757.         if {$mailalertOnIncoming} {
  758.             mailBrowser In $ids
  759.             beep; beep
  760.         }
  761.     }
  762. }
  763.  
  764.  
  765. proc mailBrowser {folder ids} {
  766.     global inboxMembers ALPHA
  767.     global tileLeft tileTop tileWidth tileHeight errorHeight
  768.  
  769.     checkMailPath
  770.     switchTo $ALPHA
  771.  
  772.     global trashedMsgs$folder
  773.     set trashedMsgs$folder {}
  774.     
  775.     set inboxMembers {}
  776.     set text {}
  777.  
  778.     foreach id $ids {
  779.         regexp {From: (.*)} [mailGetField from $folder $id] dummy from
  780.         set from [mailAddr $from]
  781.         set subject {}
  782.         regexp {Subject: (.*)} [mailGetField subject $folder $id] dummy subject
  783.         set tag {}
  784.         while {[lsearch $inboxMembers $from$tag] >= 0} {
  785.             if {![string length $tag]} {
  786.                 set tag { <2>}
  787.             } else {
  788.                 regexp {[0-9]+} $tag tag
  789.                 set tag " <[expr $tag + 1]>"
  790.             }
  791.         }
  792.         append text [format "%-40s : %s\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t░In░$id\r" "$from$tag" $subject]
  793.         lappend inboxMembers $from$tag
  794.     }
  795.     if {![string length $text]} {
  796.         alertnote "No messages!"
  797.         return
  798.     }
  799.     
  800.     if {[set ind [lsearch [winNames] "*Incoming MAILBOX*"]] >= 0} {
  801.         bringToFront [lindex [winNames] $ind]
  802.         setWinInfo read-only 0
  803.         endOfBuffer
  804.         insertText $text
  805.     } else {
  806.         killMailboxWindow
  807.         new -n "* Incoming MAILBOX *" -g $tileLeft $tileTop $tileWidth $errorHeight
  808.         global winModes
  809.         set name [lindex [winNames] 0]
  810.         changeMode [set winModes($name) Brws]
  811.     
  812.         insertText "(<cr> to go to message)\r-----\r$text"
  813.     }
  814.     select [nextLineStart [nextLineStart 0]] [nextLineStart [nextLineStart [nextLineStart 0]]]
  815.     setWinInfo dirty 0
  816.     setWinInfo read-only 1
  817.     message ""
  818. }
  819.  
  820.  
  821. proc getMsgIDs {text} {
  822.     if {[regexp -indices {seld:([0-9]+)} $text dummy ind]} {
  823.         return [concat [string range $text [lindex $ind 0] [lindex $ind 1]] [getMsgIDs [string range $text [lindex $ind 1] end]]]
  824.     }
  825. }
  826.  
  827. proc startNotifying {} {
  828.     global HOME ALPHA quitHooks
  829.     
  830.     AEBuild 'CSOm' CSOm nIns ---- [makeAlis "$HOME:$ALPHA"]
  831. #     lappend quitHooks stopNotifying
  832. }
  833.  
  834. proc stopNotifying {} {
  835.     global HOME ALPHA
  836.     
  837.     AEBuild 'CSOm' CSOm nRem ---- [makeAlis "$HOME:$ALPHA"]
  838. }
  839.